package com.generic.mybatis.dal.dao;

import com.generic.mybatis.dal.dao.criteria.Criteria;
import com.generic.mybatis.dal.dao.page.Pageable;

import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 提供最基础的操作
 *
 * @author wuaj
 */
public interface GenericDao<T, K> extends GenericOperation {

    /**
     * 根据关键字查询单条记录
     *
     * @param id 关键字
     * @return 实体对象
     */
    @Select(GET_ONE_BY_ID)
    T getOneById(K id);

    /**
     * 根据实体对象作为查询条件 查询单条记录
     *
     * @param where 实体对象条件
     * @return 实体对象
     */
    @Select(GET_ONE)
    T getOne(T where);

    /**
     * 插入记录
     *
     * @param entity 实体对象条件
     */
    @Insert(INSERT)
    void insert(T entity);

    /**
     * 更新记录
     *
     * @param entity 实体对象条件
     */
    @Update(UPDATE)
    void update(T entity);

    /**
     * 根据关键字删除记录
     * 理论删除
     *
     * @param id 关键字ID
     */
    @Delete(DELETE_BY_ID)
    void deleteById(K id);

    /**
     * 根据实体对象条件删除
     * 理论删除
     *
     * @param where 实体对象条件
     */
    @Delete(DELETE)
    void delete(T where);

    /**
     * 查询所有记录
     *
     * @return 记录列表
     */
    @Select(FIND_ALL)
    List<T> findAll();

    /**
     * 根据条件查询记录
     *
     * @param criterias 查询条件
     * @return 记录列表
     */
    @Select(FIND)
    List<T> find(Criteria... criterias);

    /**
     * 根据条件查询单列记录
     *
     * @param criterias 查询条件
     * @return 记录
     */
    @Select(FIND_ONE)
    T findOne(Criteria... criterias);

    /**
     * 根据条件查询并锁住记录集
     *
     * @param criterias 查询条件
     * @return 记录列表
     */
    @Select(FIND)
    List<T> findLock(Criteria... criterias);

    /**
     * 根据单条记录并锁住记录
     *
     * @param criterias 查询条件
     * @return 记录列表
     */
    @Select(FIND_ONE)
    T findOneLock(Criteria... criterias);

    /**
     * 分页查询
     *
     * @param pageable  分页
     * @param criterias 查询条件
     * @return 记录列表
     */
    @Select(FIND_BY_PAGE)
    List<T> findByPage(Pageable pageable, Criteria... criterias);

    /**
     * 根据条件查询记录件数
     *
     * @param criterias 查询条件
     * @return 记录件数
     */
    @Select(COUNT)
    int count(Criteria... criterias);

    /**
     * 根据条件 sum(字段)
     *
     * @param sumField  sum字段
     * @param criterias 查询条件
     * @return 合计
     */
    @Select(SUM)
    Integer sum(@Param("sumField") String sumField, @Param("criterias") Criteria... criterias);

}
